// 联合类型
type Status = number | string;
type Gender = "男" | "女";
function printStatus(data: Status): void {
  console.log(data);
}

function printGender(e: Gender): void {
  console.log(e);
}
printStatus("hello");
printGender("男");

// 交叉类型
type Area = {
  width: number; // 宽
  height: number; // 高
};
type Address = {
  country: string; // 国家
  city: string; // 城市
  address: string; // 地址
};
type House = Area & Address;

function demo(): void {
  // 返回undefined 合法
  return undefined;

  // 一下返回则不合法
  // return null
  // return 1
  // return "1"
  // return true
  // return false
  // return  {}
  // return []
}
demo();

// 先定义 void 类型的函数
type LogFunction = () => void;

// 调用 void 类型的函数可以返回 undefined 或者其他类型
const f1: LogFunction = function () {
  // return undefined
  return 66;
};

// 但是拿到的数据不可以实际操作：类似 if(xxx)
const xxx = f1(); // 66
// console.log(xxx);

// 简写前
class Person {
  // public 属性 可以直接访问 默认
  // private 属性 只能在类内部访问
  // protected 属性 只能在类内部和子类访问
  // readonly 只读属性 只能在类内部访问
  // static 静态属性 只能在类内部访问
  public name: string;
  protected readonly age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
  public speak(): void {
    console.log(`${this.name} ${this.age}`);
  }
}

// Person 简写 Person2
class Person2 {
  // public 属性 可以直接访问 默认
  // private 属性 只能在类内部访问
  // protected 属性 只能在类内部和子类访问
  // readonly 只读属性 只能在类内部访问
  // static 静态属性 只能在类内部访问
   

  constructor(
    public name: string, // 公共
    protected readonly age: number, // 保护
    private sex: string // 私有
  ) {}

  // 获取私有信息
  private getPrivateSex(): string {
    return this.sex;
  }

  // 获取公共信息
  getInfo(): string {
    return `${this.name} ${this.age}`;
  }

  // 获取全部信息
  getFullInfo(): string {
    return `${this.getInfo()} ${this.getPrivateSex()}`;
  }
  //   public speak(): void {
  //     console.log(`${this.name} ${this.age}`);
  //   }
}

const p1 = new Person2("张三", 18, "**************");
// console.log(p1)
// p1.age = 19; // 只读 属性 不可修改
console.log(p1.getFullInfo());

// Student 继承(extends) Person
class Student extends Person {
  public grade: string;
  constructor(name: string, age: number, grade: string) {
    super(name, age);
    this.grade = grade;
  }
  public study(): void {
    console.log(`${this.name} ${this.age}`);
  }
  // 覆盖 speak 方法
  override speak(): void {
    console.log(`${this.name} ${this.age} ${this.grade}`);
  }
}
const p2 = new Student("李狗", 18, "高三");
// console.log(p1)
// p2.speak();
